<?php

namespace app\admin\controller\evaluation;

use app\admin\model\EvaluationElist;
use app\admin\model\EvaluationZhuiping;
use app\admin\model\SystemAdmin;
use app\admin\model\SystemAuth;
use app\common\controller\AdminController;
use app\common\model\Users;
use app\common\service\PackService;
use think\db\Query;
use think\Request;
use EasyAdmin\annotation\ControllerAnnotation;
use EasyAdmin\annotation\NodeAnotation;
use EasyAdmin\tool\CommonTool;
use jianyan\excel\Excel;
use think\App;
use think\facade\Db;

/**
 * @ControllerAnnotation(title="evaluation_elist")
 */
class Elist extends AdminController
{

    use \app\admin\traits\Curd;

    public function __construct(App $app)
    {
        parent::__construct($app);

        $this->model = new \app\admin\model\EvaluationElist();
        $this->assign('getAdminList', SystemAdmin::where('auth_ids',8)->select()->toArray());
    }


    /**
     * @NodeAnotation(title="列表")
     */
    public function index()
    {
        $admin_id = session('admin.id');
        $userInfo = SystemAdmin::where('id',$admin_id)->find();

        if ($this->request->isAjax()) {
            if (input('selectFields')) {
                return $this->selectList();
            }
            list($page, $limit, $where) = $this->buildTableParames();
            if($userInfo['auth_ids'] == 7){
                $where[] = ['admin_id','in',explode(',',$userInfo['user_ids'])];
            }
            if($userInfo['auth_ids'] == 8){
                $where[] = ['admin_id','=',$admin_id];
            }
            $count = $this->model
                ->with(['evaluationTemplate','systemAdmin','users'])
//                ->withJoin('systemAdmin', 'LEFT')
                ->where($where)
                ->count();
            $list = $this->model
                ->with(['evaluationTemplate','systemAdmin','users'])
//                ->withJoin('systemAdmin', 'LEFT')
                ->where($where)
                ->page($page, $limit)
                ->order($this->sort)
                ->select();
            $data = [
                'code'  => 0,
                'msg'   => '',
                'count' => $count,
                'data'  => $list,
            ];
            return json($data);
        }
        return $this->fetch();
    }
    //上传视频
    public function uploadVideo(){

        $file = request()->file('file');
//        $info = $file->validate(['size'=>3145728])->move( '../public/uploads');
        $info = $file->move(ROOT_PATH . 'public' . DS . 'uploads');
        if($info){
//            var_dump($info);exit;
            $msg=['code'=>0,'msg'=>'上传成功','data'=>['src'=>'/uploads/'.str_replace('\\', '/', $info->getFilename())]];
        }else{
            $msg=['code'=>1,'msg'=>$file->getError()];
        }
        return $msg;

    }

    public function auploadVideo()
    {
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Content-type: text/html; charset=gbk32");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");

        if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
            exit; // finish preflight CORS requests here
        }
        if ( !empty($_REQUEST['debug']) ) {
            $random = rand(0, intval($_REQUEST['debug']) );
            if ( $random === 0 ) {
                header("HTTP/1.0 500 Internal Server Error");
                exit;
            }
        }
        // header("HTTP/1.0 500 Internal Server Error");
        // exit;
        // 5 minutes execution time
        set_time_limit(5 * 60);
        // Uncomment this one to fake upload time
        usleep(5000);
        // Settings

        $targetDir = ROOT_PATH . 'public'.DS.'uploads'.DS.'video_tmp';            //存放分片临时目录

        $uploadDir = ROOT_PATH . 'public'.DS.'uploads'.DS.'video'.DS.date('Ymd');    //分片合并存放目录

//        $returnPath = 'public'.DS.'uploads'.DS.'video'.DS.date('Ymd');//返回路径
        $returnPath = 'uploads'.DS.'video'.DS.date('Ymd');//返回路径

        $cleanupTargetDir = true; // Remove old files
        $maxFileAge = 5 * 3600; // Temp file age in seconds


        if (!file_exists($targetDir)) {
            mkdir($targetDir,0777,true);
        }

        if (!file_exists($uploadDir)) {
            mkdir($uploadDir,0777,true);
        }
        // Get a file name
        if (isset($_REQUEST["name"])) {
            $fileName = $_REQUEST["name"];
        } elseif (!empty($_FILES)) {
            $fileName = $_FILES["file"]["name"];
        } else {
            $fileName = uniqid("file_");
        }
        $oldName = $fileName;

        $fileName = iconv('UTF-8','gb2312',$fileName);
        $filePath = $targetDir . DS . $fileName;
        // $uploadPath = $uploadDir . DS . $fileName;
        // Chunking might be enabled
        $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
        $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 1;
        // Remove old temp files
        if ($cleanupTargetDir) {
            if (!is_dir($targetDir) || !$dir = opendir($targetDir)) {
                return json([
                    'error'   => 1,
                    'message' => '1:Failed to open temp directory'
                ]);
            }
            while (($file = readdir($dir)) !== false) {
                $tmpfilePath = $targetDir . DS . $file;
                // If temp file is current file proceed to the next
                if ($tmpfilePath == "{$filePath}_{$chunk}.part" || $tmpfilePath == "{$filePath}_{$chunk}.parttmp") {
                    continue;
                }
                // Remove temp file if it is older than the max age and is not the current file
                if (preg_match('/\.(part|parttmp)$/', $file) && (filemtime($tmpfilePath) < time() - $maxFileAge)) {
                    unlink($tmpfilePath);
                }
            }
            closedir($dir);
        }
        // Open temp file
        if (!$out = fopen("{$filePath}_{$chunk}.parttmp", "wb")) {
            return json([
                'error'   => 1,
                'message' => '2:Failed to open output stream'
            ]);
        }
        if (!empty($_FILES)) {
            if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) {
                return json([
                    'error'   => 1,
                    'message' => '3:Failed to move uploaded file'
                ]);
            }
            // Read binary input stream and append it to temp file
            if (!$in = fopen($_FILES["file"]["tmp_name"], "rb")) {
                return json([
                    'error'   => 1,
                    'message' => '4:Failed to open input stream'
                ]);
            }
        } else {
            if (!$in = fopen("php://input", "rb")) {
                return json([
                    'error'   => 1,
                    'message' => '5:Failed to open input stream'
                ]);
            }
        }
        while ($buff = fread($in, 4096)) {
            fwrite($out, $buff);
        }
        fclose($out);
        fclose($in);
        rename("{$filePath}_{$chunk}.parttmp", "{$filePath}_{$chunk}.part");
        $index = 0;
        $done = true;
        for( $index = 0; $index < $chunks; $index++ ) {
            if ( !file_exists("{$filePath}_{$index}.part") ) {
                $done = false;
                break;
            }
        }

        if ($done) {
            $pathInfo = pathinfo($fileName);
            $hashStr = substr(md5($pathInfo['basename']),8,16);
            $hashName = time() . $hashStr . '.' .$pathInfo['extension'];
            $uploadPath = $uploadDir . DS .$hashName;
            $returnPath = $returnPath . DS .$hashName;
            if (!$out = fopen($uploadPath, "wb")) {
                return json([
                    'error'   => 1,
                    'message' => '6:Failed to open output stream'
                ]);
            }
            //flock($hander,LOCK_EX)文件锁
            if ( flock($out, LOCK_EX) ) {
                for( $index = 0; $index < $chunks; $index++ ) {
                    if (!$in = fopen("{$filePath}_{$index}.part", "rb")) {
                        break;
                    }
                    while ($buff = fread($in, 4096)) {
                        fwrite($out, $buff);
                    }
                    fclose($in);
                    unlink("{$filePath}_{$index}.part");
                }
                flock($out, LOCK_UN);
            }
            fclose($out);
            $response = [
                'success'=>true,
                'oldName'=>$oldName,
                'filePath'=>$uploadPath,
                'fileSuffixes'=>$pathInfo['extension'],          //文件后缀名
            ];
            return json([
                'error'   => 0,
                'url' => 'http://'.$_SERVER['HTTP_HOST'].'/'. $returnPath
            ]);
        }
    }
    /**
     * @NodeAnotation(title="详情")
     */
    public function edit($id)
    {

        $row = $this->model->find($id)->toArray();
        empty($row) && $this->error('数据不存在');
        if ($this->request->isPost()) {
            $this->error('用户采集信息只可预览，不可修改');
            $post = $this->request->post();
            $rule = [];
            $this->validate($post, $rule);
            try {
                $save = $row->save($post);
            } catch (\Exception $e) {
                $this->error('保存失败');
            }
            $save ? $this->success('保存成功') : $this->error('保存失败');
        }
        $zhuiping = EvaluationZhuiping::with(['zhuipingUsers','zhuipingEvaluation'])->where('eva_id',$id)->where('users_id',$row['users_id'])->select() ?? [];

//        var_dump($zhuiping);exit;
        $this->assign('zhuiping', $zhuiping);
        $admin_id = session('admin.id');
        $userInfo = SystemAdmin::find($admin_id);
        if($userInfo['auth_ids'] != 1){

            foreach($row['evaluate'] as $k=> &$v){

                if($v['isanonymous'] == 1){

                    $v['star_name'] = '*';
                    $v['scores'] = '*';
                }
            }
        }
        $this->assign('row', $row);
        return $this->fetch();
    }

    /**
     * @NodeAnotation(title="导出")
     */
    public function export(Request $request)
    {
        $this->relationSearch = true;
        list($page, $limit, $where) = $this->buildTableParames();
        $admin_id = session('admin.id');
        $userInfo = SystemAdmin::where('id',$admin_id)->find();
        if($userInfo['auth_ids'] == 7){
            $where[] = ['admin_id','in',explode(',',$userInfo['user_ids'])];
        }
        if($userInfo['auth_ids'] == 8){
            $where[] = ['admin_id','=',$admin_id];
        }
        $header = [
            ['ID', 'id'],
            ['模板名称','template_name'],
            ['openid','open_id'],
            ['用户昵称','nickname'],
            ['用户头像','head_pic'],
            ['班级','class_name'],
            ['学生姓名','student_name'],
            ['评价内容','evaluate'],
            ['追评内容','evaluationZhuiping'],
            ['采集所属','username'],
            ['创建时间','create_time'],
        ];
        $list = $this->model->alias('evaluation_elist')->with(['evaluationZhuiping'=>function($query){
            $query->field('eva_id,content,create_time');
        }])->leftjoin('evaluation_template t','t.id= evaluation_elist.template_id')
            ->leftjoin('users u','u.users_id= evaluation_elist.users_id')
            ->leftjoin('system_admin admin','admin.id= evaluation_elist.admin_id')
            ->field(
                'evaluation_elist.id,
                t.name as template_name,
                u.open_id,
                u.nickname,
                u.head_pic,
                evaluation_elist.class_name,
                evaluation_elist.student_name,
                evaluation_elist.evaluate,
                admin.username,
                evaluation_elist.create_time'
            )
            ->where($where)
            ->select()->toArray();
        foreach($list as &$v){
            if($userInfo['auth_ids'] != 1){

                $isanonymous_arr = array_column($v['evaluate'],'isanonymous');
                foreach($isanonymous_arr as $kk=>$vv){
                    if($vv == 1){
                        $v['evaluate'][$kk] = ['*'];
                    }
                }
            }
            $v['evaluate'] = json_encode($v['evaluate'],JSON_UNESCAPED_UNICODE);
            $v['evaluationZhuiping'] = json_encode($v['evaluationZhuiping'],JSON_UNESCAPED_UNICODE);
        }
//        print_r($list);exit;
        $fileName = time();
        return Excel::exportData($list, $header, $fileName, 'xlsx');
    }

    public function exportzipfile()
    {
        $pack = new PackService();

        echo $pack->setPackName("test")->setDirPath("/home/wwwroot/default/testzip/")->result();
    }

    /**
     * https://www.daniao.org/2924.html 宝塔优化
     * @NodeAnotation(title="视图导出")
     */

    public function exportView(Request $request)
    {
        set_time_limit(0);
        $arr = [];
        $name = 'views';//zip名称
        $dir = ROOT_PATH .'public/';//zip所在目录
        $this->relationSearch = false;
        list($page, $limit, $where) = $this->buildTableParames();
        $admin_id = session('admin.id');
        $userInfo = SystemAdmin::where('id',$admin_id)->find();
        if($userInfo['auth_ids'] == 7){
            $where[] = ['admin_id','in',explode(',',$userInfo['user_ids'])];
        }
        if($userInfo['auth_ids'] == 8){
            $where[] = ['admin_id','=',$admin_id];
        }
       $list = Users::with(['evaluationList'=>function($query) use ($where){
            $query->where($where);
            }])->field('users_id,nickname,open_id')->select()->toArray();
       foreach ($list as $v){
           $up_dir = $dir. $name.'/' . $v['open_id'];
            if (!file_exists($up_dir) && $v['evaluationList']) {
               mkdir($up_dir, 0777, true); //不存在创建文件夹
               chmod($up_dir, 0777); //强制赋予权限
           }

            $dataList = array_column($v['evaluationList'],'evaluate');
            $views = [];
            foreach ($dataList as $vv){
                $images = array_filter(array_column($vv,'image'));
                $videos = array_filter(array_column($vv,'video'));
                if($images){
                    foreach ($images as $image){
                        $new_i = explode('|',$image);
                        array_walk_recursive($new_i, function($value) use (&$views) {
                            array_push($views, $value);
                        });
                    }

                }
                if($videos){
                    foreach ($videos as $video){
                        $new_v = explode('|',$video);
                        array_walk_recursive($new_v, function($value) use (&$views) {
                            array_push($views, $value);
                        });
                    }

                }

            }
            $arr[$v['open_id']] = $views;

       }
        $exportPath = $dir . 'views';
        $zip = new \ZipArchive();
        $dir_file = $dir .$name;
        //参数1:zip保存路径，参数2：ZIPARCHIVE::CREATE没有即是创建
        if(!$zip->open("$exportPath.zip",\ZIPARCHIVE::CREATE))
        {
            $zip->close();
            $this->error('无法创建zip');
            //echo "创建[$exportPath.zip]失败<br/>";return;
        }else{
            //本地文件加入zip , 远程文件先下载，然后加入zip。
            //$dir_file = array();

            foreach ($arr as $k=>$a) {
                if(empty($a)){
                    continue;
                }
                foreach($a as $ak=>$av){
                    $b = str_replace('http://sd.fuyexueshe.com/','',$av);
                    $c = dirname(dirname(dirname(dirname(dirname(__FILE__))))).'/public/'.$b;
                    if (file_exists($c)) {

//                        $dir_file[] = $dir .$name . '/' . $k.'/'. basename($b);;
                        $new_img   = $dir .$name . '/'. $k.'/'. basename($b);
                        copy($c , $new_img);
                    } else {
                        continue;
                    }
                }

            }
        }
        //echo "创建[$exportPath.zip]成功<br/>";
        $this->createZip(opendir($exportPath),$zip,$exportPath);
        $zip->close();
        //清空（擦除）缓冲区并关闭输出缓冲
        ob_end_clean();
        //下载建好的.zip压缩包
        header("Access-Control-Allow-Origin: *"); // 允许任意域名发起的跨域请求
        header('Access-Control-Allow-Headers: X-Requested-With,X_Requested_With');
        header("Content-Type: application/force-download");//告诉浏览器强制下载
        header("Content-Transfer-Encoding: binary");//声明一个下载的文件
        header('Content-Type: application/zip');//设置文件内容类型为zip
        header('Content-Disposition: attachment; filename='.$name.'.zip');//声明文件名
        header('Content-Length: '.filesize("$exportPath.zip"));//声明文件大小
        error_reporting(0);
        //将欲下载的zip文件写入到输出缓冲
        readfile("$exportPath.zip");
        //将缓冲区的内容立即发送到浏览器，输出
        flush();
        unlink("$exportPath.zip");//导出zip 后，原先的文件夹清空（视情况而操作）
        $this->deldir($dir_file);
//        foreach($dir_file as $d){
//            $this->deldir($d);
//            //unlink($d);
//        }
        exit;


    }
    public  function deldir($path){
        //如果是目录则继续
        if(is_dir($path)){
             //扫描一个文件夹内的所有文件夹和文件并返回数组
            $p = scandir($path);
            foreach($p as $val){
                //排除目录中的.和..
                if($val !="." && $val !=".."){
                //如果是目录则递归子目录，继续操作
                    if(is_dir($path.'/'.$val)){
                        //子目录中操作删除文件夹和文件
                        $this->deldir($path.'/'.$val);
                        //目录清空后删除空文件夹
                        @rmdir($path.'/'.$val);
                    }else{
                        //如果是文件直接删除
                        unlink($path.'/'.$val);
                    }
                }
            }
        }
    }

    /*压缩多级目录
        参考文献 https://www.cnblogs.com/zhaoying/p/16401172.html
        $openFile:目录句柄
        $zipObj:Zip对象
        $sourceAbso:源文件夹路径
    */
    function createZip($openFile,$zipObj,$sourceAbso,$newRelat = '')
    {
        while(($file = readdir($openFile)) != false)
        {
            if($file=="." || $file=="..")
                continue;

            /*源目录路径(绝对路径)*/
            $sourceTemp = $sourceAbso.'/'.$file;
            /*目标目录路径(相对路径)*/
            $newTemp = $newRelat==''?$file:$newRelat.'/'.$file;
            if(is_dir($sourceTemp))
            {
                //echo '创建'.$newTemp.'文件夹<br/>';
                $zipObj->addEmptyDir($newTemp);/*这里注意：php只需传递一个文件夹名称路径即可*/
                $this->createZip(opendir($sourceTemp),$zipObj,$sourceTemp,$newTemp);
            }
            if(is_file($sourceTemp))
            {
                //echo '创建'.$newTemp.'文件<br/>';
                $zipObj->addFile($sourceTemp,$newTemp);
            }
        }
    }


}